﻿using System;
using System.Windows;
using System.Windows.Data;
using MVVM.Northwind.Employee.Commands;
using System.Windows.Input;
using System.Collections.ObjectModel;
using MVVM.Northwind.Employee.Utilities;
using MVVM.Northwind.Employee.Services;

namespace MVVM.Northwind.Employee.ViewModel
{
    public class EmployeeListViewModel:WorkspaceViewModel
    {
        // EmployeeList ViewModel will have a collection
        // of all employees. This will be bound to the 
        // User control.        
        #region Private Members
        private ICommand _searchEmployeeCommand;
       
        private ICommand _saveEmployeeCommand;
        private ICommand _cancelEmployeeCommand;
        private ICommand _deleteEmployeeCommand;
        
        #endregion       

        /// <summary>
        /// Constructor
        /// </summary>
        public EmployeeListViewModel()
        {
            try
            {                
                LoadEmployeeCollection();
            }
            catch (Exception ex)
            {
                ErrorHandler.ErrorMessage = ex.Message;
                throw;
            }
        }

        private void LoadEmployeeCollection()
        {
            Model.EmployeeRepository eRep = new Model.EmployeeRepository();
            this.Employees = new ObservableCollection<DataAccess.Employee>(eRep.GetEmployees());
            this.EmployeeCollection = new CollectionViewSource();
            this.EmployeeCollection.Source = this.Employees;
        }

        #region Public Properties

        public CollectionViewSource EmployeeCollection { get; set; }        
        private ObservableCollection<DataAccess.Employee> Employees { get; set; }
        
        public ObservableCollection<DataAccess.Employee> SearchedEmployees { get; private set; }
        public string SearchText { get; set; }
        
        #endregion

        
        #region Command Properties
        public ICommand SearchEmployeeCommand
        {
            get
            {
                _searchEmployeeCommand = new MVVMRoutedCommand
                    ((param) => this.SearchCommandExecute(), param => this.SearchCommandCanExecute());
                return _searchEmployeeCommand;
            }
        }
        
        public ICommand SaveEmployeeCommand
        {
            get
            {
                if (_saveEmployeeCommand==null)
                {
                    _saveEmployeeCommand = new MVVMRoutedCommand
                    ((param) => this.SaveEmployeeCommandExecute(), (param) => this.SaveEmployeeCommandCanExecute());                    
                }
                return _saveEmployeeCommand;
            }
        }

        public ICommand CancelEmployeeCommand
        {
            get
            {
                if (_cancelEmployeeCommand==null)
                {
                    _cancelEmployeeCommand = new MVVMRoutedCommand
                    ((param) => this.CancelEmployeeCommandExecute(), (param) => this.CancelEmployeeCommandCanExecute());                                        
                }
                return _cancelEmployeeCommand;
            }
        }

        public ICommand DeleteEmployeeCommand
        {
            get
            {
                if (_deleteEmployeeCommand==null)
                {
                    _deleteEmployeeCommand = new MVVMRoutedCommand
                    ((param) => this.DeleteEmployeeCommandExecute(), (param) => this.DeleteEmployeeCommandCanExecute());
                }                
                return _deleteEmployeeCommand;
            }
        }
        #endregion

        #region Command Behaviors

        /// <summary>
        /// 
        /// </summary>
        private void SearchCommandExecute()
        {
            Model.EmployeeRepository eRep = new Model.EmployeeRepository();
            this.SearchedEmployees = new ObservableCollection<DataAccess.Employee>(eRep.SearchEmployees(this.SearchText));
            OnPropertyChanged("SearchedEmployees");
        }

        private bool SearchCommandCanExecute()
        {
            //return true;
            if (this.Employees.Count > 0)
                return true;
            else
                return false;
        }        

        /// <summary>
        /// 
        /// </summary>
        private void SaveEmployeeCommandExecute()
        {
            DataAccess.Employee updatedEmployee = this.EmployeeCollection.View.CurrentItem as DataAccess.Employee;
            DataAccess.DatabaseGateway dbGwy = DataAccess.DatabaseGateway.CreateInstance();
            dbGwy.UpdateEmployee(updatedEmployee);
            ServiceContainer.Instance.AddService<IMessageBoxService>(new MessageBoxService());
            Saved();
        }
        private bool SaveEmployeeCommandCanExecute()
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void CancelEmployeeCommandExecute()
        {
            // show message box: warning - cancel will result in loss of all changes
            if (Cancelling())
            {
                // Cancel all the changes and revert to original            
                LoadEmployeeCollection();
                Cancelled();
            }
        }

        private bool CancelEmployeeCommandCanExecute()
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void DeleteEmployeeCommandExecute()
        {
            if (Deleting())
            {
                DataAccess.Employee deletedEmployee = this.EmployeeCollection.View.CurrentItem as DataAccess.Employee;
                DataAccess.DatabaseGateway dbGwy = DataAccess.DatabaseGateway.CreateInstance();
                dbGwy.DeleteEmployee(deletedEmployee.EmployeeID);
                Deleted();
            }
            
        }

        private bool DeleteEmployeeCommandCanExecute()
        {
            return true;
        }

        #endregion
        
        protected override void OnDispose()
        {
            this.Employees.Clear();
            this.SearchedEmployees.Clear();
        }

        #region Pop Up Window Methods

        /// <summary>
        /// 
        /// </summary>
        private void Saved()
        {
            var msgBox = base.GetService<IMessageBoxService>();
            if (msgBox != null)
            {
                msgBox.Show("Your changes have been saved in the database", "Save Data",
                    System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private bool Cancelling()
        {
            var msgBox = base.GetService<IMessageBoxService>();
            if (msgBox != null)
            {
                MessageBoxResult result =
                    msgBox.Show("Your changes, if any, will be lost", "Cancel Changes",
                    MessageBoxButton.OKCancel, MessageBoxImage.Question);
                if (result == MessageBoxResult.OK)
                    return true;
                else
                    return false;
            }
            else
                return false;
        }

        /// <summary>
        /// 
        /// </summary>
        private void Cancelled()
        {
            var msgBox = base.GetService<IMessageBoxService>();
            if (msgBox != null)
            {
                MessageBoxResult result =
                msgBox.Show("Your actions have been cancelled. Data has been raverted", "Cancel Data",
                MessageBoxButton.OKCancel, MessageBoxImage.Information);
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private bool Deleting()
        {
            var msgBox = base.GetService<IMessageBoxService>();
            if (msgBox != null)
            {
                MessageBoxResult result =
                msgBox.Show("Your record will be deleted. Are you sure?", "Delete Data",
                MessageBoxButton.OKCancel, MessageBoxImage.Question);
                if (result == MessageBoxResult.OK)
                    return true;
                else
                    return false;
            }
            else
                return false;
        }

        /// <summary>
        /// 
        /// </summary>
        private void Deleted()
        {
            var msgBox = base.GetService<IMessageBoxService>();
            if (msgBox != null)
            {
                MessageBoxResult result =
                msgBox.Show("Data has been deleted", "Delete Data",
                MessageBoxButton.OKCancel, MessageBoxImage.Information);
            }
        }

        #endregion        
    }
}
